﻿<script src="../source/LexicalParser.js"></script>
<script src="../source/SyntacticalParser.js"></script>
<script src="../source/Parser.js"></script>
<style>
.Keyword, .NullLiteral, .BooleanLiteral {
    color:blue;
}
.StringLiteral {
    color:red;
}
.RegularExpressionLiteral {
    color:red;
}
.NumericLiteral {
    color:purple;
}
 {
    color:purple;
}
</style>

<pre id="output"></pre>
<textarea id="code" style="width:100%;height:500px;">var bubbleSort = function (array) {
    for (var x = 0; x < array.length; x++) {
        for (var y = 0; y < array.length - x; y++) {
            if (array[y] > array[y + 1]) {
                swap(array, y, y + 1);
            }
        }
    }
}</textarea>
<button >parse</button>
<script>
var configs = {
    indentStyle:"Microsoft"
};

function getClassName(token) {
    var classNames = ["InputElement","Comments","SingleLineComments","MultiLineComments","WhiteSpace","Token","IdentifierName","Identifier","Keyword","NullLiteral","BooleanLiteral","Punctuator","NumericLiteral","StringLiteral","RegularExpressionLiteral","LineTerminator"];
    return classNames.filter(function(e){ return token.hasOwnProperty(e); }).join(" ");
}

document.querySelector("button").onclick = function(){
    var parser = new Parser();
    var tree = parser.parse(document.querySelector("#code").value);

    var str = "";
    var output = document.querySelector("#output");
    output.innerHTML = "";
    var indent = 0;
    var last = null;
    var table = {"|=":true,"^=":true,"&=":true,">>>=":true,">>=":true,"<<=":true,"-=":true,"+=":true,"%=":true,"/=":true,"*=":true,"=":true,"?":true,"||":true,"&&":true,"|":true,"^":true,"&":true,"!==":true,"===":true,"!=":true,"==":true,">=":true,"<=":true,">":true,"<":true,">>>":true,">>":true,"<<":true,"-":true,"+":true,"%":true,"*":true,"/":true}

    function visitObj(obj) {
        visit(obj.childNodes[obj.childNodes.length-1]);
        if(obj.childNodes.length>=3)
        {
            var list = obj.childNodes[obj.childNodes.length-2];
            while(list.name == "PropertyNameAndValueList" && list.childNodes.length>2) {
                output.appendChild(document.createElement("br"));
                var indentSpan = document.createElement("span");
                indentSpan.innerHTML = Array(indent+1).join(" ");
                output.appendChild(indentSpan);
                visit(list.childNodes[0]);
                visit(list.childNodes[1]);
                list = list.childNodes[list.childNodes.length-1];
            }
            visit(list);
        }
        output.appendChild(document.createElement("br"));
        var indentSpan = document.createElement("span");
        indentSpan.innerHTML = Array(indent+1).join(" ");
        output.appendChild(indentSpan);
        visit(obj.childNodes[0]);
    }


    function visit(tree) {
        var haveIndent;

        if(tree.name=="ObjectLiteral") {
            return visitObj(tree);
        }

        if( last!="return" && (tree.name == "Statement" ||tree.name == "FunctionDeclaration"  ||tree.name == "FunctionExpression")  && tree.childNodes[0].name!="Block") {
            output.appendChild(document.createElement("br"));
            var indentSpan = document.createElement("span");
            indentSpan.innerHTML = Array(indent+1).join(" ");
            output.appendChild(indentSpan);
            indent+=4;
            last = null;
            haveIndent = true;
        }

        if(tree.token) {
            if( last ){
                if((tree.token.Identifier || tree.token.Keyword|| tree.token.NumericLiteral|| tree.token.StringLiteral|| tree.token.NullLiteral|| tree.token.BooleanLiteral|| tree.token.RegularExpressionLiteral) && (last.Identifier || last.Keyword|| last.NumericLiteral|| last.StringLiteral|| last.NullLiteral|| last.BooleanLiteral|| last.RegularExpressionLiteral)) output.appendChild(document.createTextNode(" "));;
                if(tree.token.NumericLiteral && last.name == "." || last.name == "." && tree.token.NumericLiteral) output.appendChild(document.createTextNode(" "));
            }
            if(tree.token == "}") {
                output.appendChild(document.createElement("br"));
                var indentSpan = document.createElement("span");
                indentSpan.innerHTML = Array(indent+1-4).join(" ");
                output.appendChild(indentSpan);
            }
            if(tree.token == "else") {
                output.appendChild(document.createElement("br"));
                var indentSpan = document.createElement("span");
                indentSpan.innerHTML = Array(indent+1-4).join(" ");
                output.appendChild(indentSpan);
            }
            if(tree.token == "{") {
                output.appendChild(document.createElement("br"));
                var indentSpan = document.createElement("span");
                indentSpan.innerHTML = Array(indent+1-4).join(" ");
                output.appendChild(indentSpan);
            }
 
            if(table[tree.token]) output.appendChild(document.createTextNode(" "));
            var token = document.createElement("span");
            token.className = getClassName(tree.token);
            token.appendChild(document.createTextNode(tree.token));
            output.appendChild(token);
            if(tree.token==",") output.appendChild(document.createTextNode(" "));
            if(table[tree.token]) output.appendChild(document.createTextNode(" "));
            last = tree.token;
        }
        else {
            var i = tree.childNodes.length;
            while(i--) {
                visit(tree.childNodes[i]);
            }
        }
        if( haveIndent ) {
            indent-=4;
        }
    }
    visit(tree);
    
}

</script>